﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BrightIdeasSoftware;
using System.Data;
using System.Windows.Forms;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Reflection;
namespace UIControls.Grid
{
    public class OSGrid : ObjectListView
    {
        public OSGrid()
            : base()
        {
            SetStyle(
                ControlStyles.AllPaintingInWmPaint |
                ControlStyles.OptimizedDoubleBuffer, true);
            this.ShowGroups = false;
            this.UseAlternatingBackColors = true;
            this.UseCustomSelectionColors = true;
            this.UseTranslucentSelection = true;
            this.HideSelection = false;
            this.Font = GlobalUIVar.gFont;
            this.EmptyListMsg = "没有记录";
            this.GridLines = false;
            this.BackColor = SystemColors.Control;
           
        }
        
      
        OLVListItem activedItem;
        Color beforeActiviedColor;
        protected override void FillInValues(OLVListItem lvi, object rowObject)
        {
            base.FillInValues(lvi,rowObject);
            lvi.BackColor = Color.White;
        }
        /// <summary>
        /// Do the work required after one item in a listview have been created
        /// </summary>
        protected override void PostProcessOneRow(int rowIndex, int displayIndex, OLVListItem olvi)
        {
            base.PostProcessOneRow(rowIndex, displayIndex, olvi);
       
            if (this.UseAlternatingBackColors && this.View == View.Details)
            {
                if (displayIndex % 2 == 1)
                {
                    olvi.BackColor = this.AlternateRowBackColorOrDefault;
                }
                else
                {
                    olvi.BackColor = Color.White;
                }
            }

        }
        /// <summary>
        /// This event is triggered when the contents of a list have changed
        /// and we want the world to have a chance to filter the list.
        /// </summary>
        public class FilterdEventArgs : EventArgs
        {
            /// <summary>
            /// Create a FilterEventArgs
            /// </summary>
            /// <param name="objects"></param>
            public FilterdEventArgs(IEnumerable objects)
            {
                this.FilteredObjects = objects;
            }


            /// <summary>
            /// Gets or sets what objects survived the filtering
            /// </summary>
            public IEnumerable FilteredObjects;
        }

        public void SetObjects(DataTable dt)
        {
            this.Columns.Clear();
            foreach (DataColumn c in dt.Columns)
            {
                OLVColumn oc = new OLVColumn(c.Caption, c.ColumnName);

                this.Columns.Add(oc);
            }
            base.SetObjects(dt.DefaultView);
        }

        public DataTable GenerateDataTable()
        {

            var dt = new DataTable();
            foreach (OLVColumn c in this.Columns)
            {
                var col = new DataColumn(c.Text);

                dt.Columns.Add(col);
            }
            foreach (OLVListItem item in this.Items)
            {
                var row = dt.NewRow();
                for (int i = 0; i < dt.Columns.Count; i++)
                {

                    row[i] = item.SubItems[i].Text;

                }
                dt.Rows.Add(row);
            }

            return dt;
        }

        DataTable gettable()
        {
            if (this.Objects == null)
                return null;
            if (this.Objects is DataView)
            {
                var v = this.Objects as DataView;

                return v.Table;
            }
            var dt = new DataTable();
            foreach (OLVColumn c in this.Columns)
            {
                var col = new DataColumn(c.AspectName);

                dt.Columns.Add(col);
            }
            if (this.GetItemCount() != 0)
            {
                Type ot = (this.Items[0] as OLVListItem).RowObject.GetType();

                foreach (BrightIdeasSoftware.OLVListItem item in this.Items)
                {
                    var obj = item.RowObject;
                    var pi = ot.GetProperties();
                    var row = dt.NewRow();
                    foreach (DataColumn dc in dt.Columns)
                    {
                        var pv = ot.GetProperty(dc.ColumnName).GetValue(obj, null);

                        row[dc.ColumnName] = pv;

                    }
                    dt.Rows.Add(row);
                }
            }
            foreach (OLVColumn c in this.Columns)
            {

                dt.Columns[c.AspectName].ColumnName = c.Text;
            }
            return dt;
        }

        string GetColumnAspecter(string columnName)
        {
            foreach (OLVColumn col in this.Columns)
            {
                if (col.Text == columnName)
                    return col.AspectName;
            }
            return null;
        }
        private Type _RowObjectType;
        public Type RowObjectType { get { return _RowObjectType; } set { _RowObjectType = value; } }
        public void AddRowsFromDataTable(DataTable src)
        {
            if (src == null)
                return;
            foreach (DataColumn c in src.Columns)
            {
                if (c.ColumnName.StartsWith("F", StringComparison.CurrentCultureIgnoreCase))
                    continue;
                if (GetColumnAspecter(c.ColumnName) == null)
                    return;
            }
            //如果列都在这里面.
            var asm = Assembly.Load(BO.GlobalVar.BOAssembly);
            List<object> objs = new List<object>();
            foreach (DataRow row in src.Rows)
            {
                var newObj = asm.CreateInstance(RowObjectType.FullName);
                foreach (DataColumn c in src.Columns)
                {
                    var propertyName = GetColumnAspecter(c.ColumnName);
                    if (propertyName == null)
                        continue;
                    var val = row[c.ColumnName];
                    if (val == null || val is DBNull)
                        continue;
                    var strVal = val.ToString();
                    var p = RowObjectType.GetProperty(propertyName);
                    if (p.PropertyType == typeof(Boolean))
                    {
                        val = val.ToString() == "是" ? true : false;
                    }
                   
                    var covertObj = Convert.ChangeType(val, p.PropertyType);

                    p.SetValue(newObj, covertObj, null);

                }
                objs.Add(newObj);

            }
            this.InsertObjects(0, objs);
        }

        /// <summary>
        /// Do the actual work of filtering
        /// </summary>
        /// <param name="objects"></param>
        /// <param name="aModelFilter"></param>
        /// <param name="aListFilter"></param>
        /// <returns></returns>
        protected override IEnumerable FilterObjects(IEnumerable objects, IModelFilter aModelFilter, IListFilter aListFilter)
        {


            // Being cautious
            objects = objects ?? new ArrayList();
            // Tell the world to filter the objects. If they do so, don't do anything else
            FilterEventArgs args = new FilterEventArgs(objects);
            this.OnFilter(args);

            if (args.FilteredObjects != null)
                return args.FilteredObjects;

            // Apply a filter to the list as a whole
            if (aListFilter != null)
                objects = aListFilter.Filter(objects);

            // Apply the object filter if there is one
            if (aModelFilter != null)
            {
                ArrayList filteredObjects = new ArrayList();
                foreach (object model in objects)
                {
                    if (aModelFilter.Filter(model))
                        filteredObjects.Add(model);
                }
                objects = filteredObjects;
                FilterdEventArgs args2 = new FilterdEventArgs(objects);
                this.OnFilterd(args2);

            }

            return objects;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnFilterd(FilterdEventArgs e)
        {
            if (this.Filterd != null)
                this.Filterd(this, e);
        }
        /// <summary>
        /// This event is triggered when the control needs to filter its collection of objects.
        /// </summary>
        [Category("ObjectListView"),
        Description("This event is triggered when the control needs to filter its collection of objects.")]
        public event EventHandler<FilterdEventArgs> Filterd;



        private string _LabelText = string.Empty;
        public string LabelText
        {
            get { return _LabelText; }
            set
            {
                if (value == null)
                    _LabelText = string.Empty;
                else
                    _LabelText = value;
            }
        }

        //public override ToolStripDropDown MakeFilteringMenu(ToolStripDropDown strip, int columnIndex)
        //{
        //    var tool = base.MakeFilteringMenu(strip, columnIndex);
        //    tool.Height = 500;
        //    return tool;
        //}

    
    }

    
}
